package com.atguigu.lease.web.admin.service.impl;

import com.atguigu.lease.common.advice.LeaseException;
import com.atguigu.lease.common.result.ResultCodeEnum;
import com.atguigu.lease.model.entity.*;
import com.atguigu.lease.model.enums.ItemType;
import com.atguigu.lease.model.enums.LeaseStatus;
import com.atguigu.lease.model.enums.ReleaseStatus;
import com.atguigu.lease.web.admin.mapper.RoomInfoMapper;
import com.atguigu.lease.web.admin.service.*;
import com.atguigu.lease.web.admin.vo.graph.GraphVo;
import com.atguigu.lease.web.admin.vo.room.RoomDetailVo;
import com.atguigu.lease.web.admin.vo.room.RoomItemVo;
import com.atguigu.lease.web.admin.vo.room.RoomQueryVo;
import com.atguigu.lease.web.admin.vo.room.RoomSubmitVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author liubo
 * @description 针对表【room_info(房间信息表)】的数据库操作Service实现
 * @createDate 2023-07-24 15:48:00
 */
@Service
public class RoomInfoServiceImpl extends ServiceImpl<RoomInfoMapper, RoomInfo> implements RoomInfoService {
    @Autowired
    private RoomInfoMapper roomInfoMapper;
    @Autowired
    private GraphInfoService graphInfoService;
    @Autowired
    private RoomLabelService roomLabelService;
    @Autowired
    private RoomFacilityService roomFacilityService;
    @Autowired
    private RoomLeaseTermService roomLeaseTermService;
    @Autowired
    private RoomPaymentTypeService roomPaymentTypeService;
    @Autowired
    private RoomAttrValueService roomAttrValueService;
    @Autowired
    private LeaseAgreementService leaseAgreementService;
    @Override
    public void customPage(Page<RoomItemVo> page, RoomQueryVo queryVo) {
        roomInfoMapper.customSelectAll(page, queryVo);
    }

    @Override
    public RoomDetailVo customGetById(Long id) {
        return roomInfoMapper.customSelectById(id);
    }

    /**
 * 保存房间信息及其关联信息
 * 如果房间已存在，则更新房间信息；否则，插入新房间信息
 * 此方法还负责处理与房间相关的子表数据，如图形信息、标签、设施、租赁条款和支付方式
 *
 * @param roomSubmitVo 房间提交对象，包含房间基本信息及其关联信息
 */
@Override
public void customSave(RoomSubmitVo roomSubmitVo) {
    // 判断房间是否存在
    boolean exits = roomSubmitVo.getId() != null;
    // 保存或更新房间信息
    saveOrUpdate(roomSubmitVo);

    // 如果房间已存在，删除原有的子表数据，以支持重新保存最新的关联信息
    if (exits) {
        delectSonTable(roomSubmitVo.getId(), ItemType.ROOM);
    }

    // 处理图形信息
    List<GraphVo> graphVoList = roomSubmitVo.getGraphVoList();
    if (!CollectionUtils.isEmpty(graphVoList)) {
        List<GraphInfo> graphInfoList = new ArrayList<>(graphVoList.size());
        for (GraphVo graphVo : graphVoList) {
            GraphInfo graphInfo = new GraphInfo();
            graphInfo.setName(graphVo.getName());
            graphInfo.setUrl(graphVo.getUrl());
            graphInfo.setItemId(roomSubmitVo.getId());
            graphInfo.setItemType(ItemType.ROOM);
            graphInfoList.add(graphInfo);
        }
        // 批量保存图形信息
        graphInfoService.saveBatch(graphInfoList);
    }

    // 处理标签信息
    List<Long> labelInfoIds = roomSubmitVo.getLabelInfoIds();
    if (!CollectionUtils.isEmpty(labelInfoIds)) {
        List<RoomLabel> roomLabelList = new ArrayList<>(labelInfoIds.size());
        for (Long labelInfoId : labelInfoIds) {
            RoomLabel roomLabel = RoomLabel.builder().roomId(roomSubmitVo.getId())
                    .labelId(labelInfoId).build();
            roomLabelList.add(roomLabel);
        }
        // 批量保存房间标签关联信息
        roomLabelService.saveBatch(roomLabelList);
    }

    // 处理设施信息
    List<Long> facilityInfoIds = roomSubmitVo.getFacilityInfoIds();
    if (!CollectionUtils.isEmpty(facilityInfoIds)) {
        List<RoomFacility> roomFacilityList = new ArrayList<>(facilityInfoIds.size());
        for (Long facilityInfoId : facilityInfoIds) {
            RoomFacility roomFacility = RoomFacility.builder().roomId(roomSubmitVo.getId())
                    .facilityId(facilityInfoId).build();
            roomFacilityService.save(roomFacility);
        }
        // 批量保存房间设施关联信息
        roomFacilityService.saveBatch(roomFacilityList);
    }

    // 处理租赁条款信息
    List<Long> leaseTermIds = roomSubmitVo.getLeaseTermIds();
    if (!CollectionUtils.isEmpty(leaseTermIds)) {
        List<RoomLeaseTerm> roomLeaseTermList = new ArrayList<>(leaseTermIds.size());
        for (Long leaseTermId : leaseTermIds) {
            RoomLeaseTerm roomLeaseTerm = RoomLeaseTerm.builder().roomId(roomSubmitVo.getId())
                    .leaseTermId(leaseTermId).build();
            roomLeaseTermList.add(roomLeaseTerm);
        }
        // 批量保存房间租赁条款关联信息
        roomLeaseTermService.saveBatch(roomLeaseTermList);
    }

    // 处理支付方式信息
    List<Long> paymentTypeIds = roomSubmitVo.getPaymentTypeIds();
    if (!CollectionUtils.isEmpty(paymentTypeIds)) {
        List<RoomPaymentType> roomPaymentTypeList = new ArrayList<>(paymentTypeIds.size());
        for (Long paymentTypeId : paymentTypeIds) {
            RoomPaymentType roomPaymentType = RoomPaymentType.builder().roomId(roomSubmitVo.getId())
                    .paymentTypeId(paymentTypeId).build();
            roomPaymentTypeList.add(roomPaymentType);
        }
        // 批量保存房间支付方式关联信息
        roomPaymentTypeService.saveBatch(roomPaymentTypeList);
    }

    // 处理属性值信息
    List<Long> attrValueIds = roomSubmitVo.getAttrValueIds();
    if (!CollectionUtils.isEmpty(attrValueIds)) {
        List<RoomAttrValue> roomAttrValueList = new ArrayList<>(attrValueIds.size());
        for (Long attrValueId : attrValueIds) {
            RoomAttrValue roomAttrValue = RoomAttrValue.builder().roomId(roomSubmitVo.getId())
                    .attrValueId(attrValueId).build();
            roomAttrValueList.add(roomAttrValue);
        }
        // 批量保存房间属性值关联信息
        roomAttrValueService.saveBatch(roomAttrValueList);
    }
}

    /**
 * 根据ID自定义删除记录
 * 该方法首先检查给定ID相关的租赁协议是否存在如果存在，则抛出删除错误异常
 * 这是为了确保数据的完整性，避免删除了有租赁协议的房间ID
 * 如果不存在租赁协议，则继续删除子表中的相关记录，然后删除当前表中的记录
 *
 * @param id 要删除的记录的ID
 */
@Override
public void customRemoveById(Long id) {
    // 创建Lambda更新封装器，用于条件查询
    LambdaUpdateWrapper<LeaseAgreement> leaseAgreementLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
    // 设置查询条件：根据房间ID等于给定的ID
    leaseAgreementLambdaUpdateWrapper.eq(LeaseAgreement::getRoomId, id);
    leaseAgreementLambdaUpdateWrapper.in(LeaseAgreement::getStatus, LeaseStatus.SIGNED,LeaseStatus.WITHDRAWING,LeaseStatus.RENEWING);
    // 计算满足条件的租赁协议数量
    long count = leaseAgreementService.count(leaseAgreementLambdaUpdateWrapper);
    // 如果存在相关的租赁协议，抛出删除错误异常
    if (count > 0) {
        throw new LeaseException(ResultCodeEnum.DELETE_ERROR);
    }
    // 删除子表中的相关记录
    delectSonTable(id, ItemType.ROOM);
    // 删除当前表中的记录
    removeById(id);
}


    /**
 * 根据物品ID和类型删除相关子表记录
 * 此方法旨在清理与特定物品相关的所有子表数据，确保数据一致性
 *
 * @param id 物品ID，用于定位相关子表记录
 * @param itemType 物品类型，与物品ID一起用于精确查找GraphInfo表中的记录
 */
private void delectSonTable(Long id, ItemType itemType) {
    // 删除GraphInfo表中与指定物品ID和类型匹配的记录
    LambdaQueryWrapper<GraphInfo> graphInfoLambdaQueryWrapper = new LambdaQueryWrapper<>();
    graphInfoLambdaQueryWrapper.eq(GraphInfo::getItemId, id).eq(GraphInfo::getItemType, itemType);
    graphInfoService.remove(graphInfoLambdaQueryWrapper);

    // 删除RoomLabel表中与指定房间ID匹配的记录
    LambdaQueryWrapper<RoomLabel> roomLabelLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roomLabelLambdaQueryWrapper.eq(RoomLabel::getRoomId, id);
    roomLabelService.remove(roomLabelLambdaQueryWrapper);

    // 删除RoomFacility表中与指定房间ID匹配的记录
    LambdaQueryWrapper<RoomFacility> roomFacilityLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roomFacilityLambdaQueryWrapper.eq(RoomFacility::getRoomId, id);
    roomFacilityService.remove(roomFacilityLambdaQueryWrapper);

    // 删除RoomLeaseTerm表中与指定房间ID匹配的记录
    LambdaQueryWrapper<RoomLeaseTerm> roomLeaseTermLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roomLeaseTermLambdaQueryWrapper.eq(RoomLeaseTerm::getRoomId, id);
    roomLeaseTermService.remove(roomLeaseTermLambdaQueryWrapper);

    // 删除RoomPaymentType表中与指定房间ID匹配的记录
    LambdaQueryWrapper<RoomPaymentType> roomPaymentTypeLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roomPaymentTypeLambdaQueryWrapper.eq(RoomPaymentType::getRoomId, id);
    roomPaymentTypeService.remove(roomPaymentTypeLambdaQueryWrapper);

    // 删除RoomAttrValue表中与指定房间ID匹配的记录
    LambdaQueryWrapper<RoomAttrValue> roomAttrValueLambdaQueryWrapper = new LambdaQueryWrapper<>();
    roomAttrValueLambdaQueryWrapper.eq(RoomAttrValue::getRoomId, id);
    roomAttrValueService.remove(roomAttrValueLambdaQueryWrapper);
}

}




